home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
clean
/
sun3.lha
/
Sun3
/
seqdemos
/
squeen.icl
< prev
next >
Wrap
Text File
|
1992-08-07
|
2KB
|
72 lines
MODULE squeen;
<<
The Queens Problem.
Or: How to put n queens on a n*n chessboard in such a way that they
cannot attack each other.
The result of this program is the number of possible solutions for
the queens problem for a certain boardsize together with one solution.
When BoardSize is 8 the result will be: (92,[4,2,7,3,6,8,5,1]),
which means the queens are on a4, b2, c7, d3, e6, f8, g5 and h1.
Strictness annotations are used at certain points, because that makes
this program more than twice as fast (the strictness analyzer is not
able to deduce this strictness information). However, other Clean programs
for the Queens problem exist without strictness annotations added by the
programmer that are only 40% slower than this solution (lqueen.icl).
>>
IMPORT deltaI;
MACRO
BoardSize -> 8; == The size of the chessboard.
RULE
== Miscellaneous list functions.
:: Length [x] -> INT;
Length [hd|tl] -> ++ (Length tl);
Length [] -> 0;
:: Head [x] -> x;
Head [hd|tl] -> hd;
== Finding all solutions for the queens problem.
:: Queens INT [INT] [[INT]] -> [[INT]];
Queens row board boards -> [board | boards] , IF > row BoardSize
-> TryCols BoardSize row board boards;
:: TryCols INT INT [INT] [[INT]] -> [[INT]];
TryCols 0 row board boards -> boards;
TryCols col row board boards
-> TryCols (-- col) row board queens , IF Save col 1 board
-> TryCols (-- col) row board boards,
queens: Queens (++ row) [col | board] boards;
<< The strictness analyzer can't derive strictness for the first and second
argument of Save, because they are not used in the first alternative
of that function. However, Save is strict in these arguments (in the
context of this program) and adding the strictness annotations speeds
up this program considerably.
>>
:: Save !INT !INT [INT] -> BOOL;
Save c1 rdiff [] -> TRUE;
Save c1 rdiff [c2|cols]
-> FALSE , IF = cdiff 0 || = cdiff rdiff || = cdiff (- 0 rdiff)
-> Save c1 (++ rdiff) cols,
cdiff: - c1 c2;
<< The Start Rule: Calculate the list of solutions, show the first
solution and the length of that list.
>>
:: Start -> (INT,[INT]);
Start -> (Length solutions, Head solutions),
solutions: Queens 1 [] [];